package mmpathgen.callgraphanalysis;

import java.io.File;

import mmpathgen.util.ClassLoader;
import mmpathgen.util.JRELibFilter;
import soot.Scene;
import soot.jimple.toolkits.annotation.purity.SootMethodFilter;
import soot.jimple.toolkits.callgraph.CHATransformer;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.options.Options;

public class CallGraphGenByCHA {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// get the class names automatically
		File path = new File("D:\\workspace\\MMPath\\basic");

		// set main application class
		String mainClassName = "basic.HelloWorld";

		CallGraph cg = cgGen(path, mainClassName);
		
		UnfilteredCallGraph ucg = CallGraphAnalysis.getUnfilteredCallGraph(cg);

		CallGraphAnalysis.printCallGraphAsDot(ucg, mainClassName, "CHA", "Unfilted");

		SootMethodFilter filter = new JRELibFilter();
		
		FilteredCallGraph fcg = CallGraphAnalysis.getFilteredCallGraph(cg, filter);

		CallGraphAnalysis.printCallGraphAsDot(fcg, mainClassName, "CHA", "Filted");
	}

	public static CallGraph cgGen(File path, String mainClassName) {
		Options.v().set_whole_program(true);
		Options.v().set_keep_line_number(true);
		// Options.v().setPhaseOption("cg", "verbose:true");
		Options.v().setPhaseOption("cg", "safe-forname:true");
		Options.v().setPhaseOption("cg", "safe-newinstance:true");

		ClassLoader.loadClass(path, mainClassName);

		CHATransformer.v().transform();

		CallGraph cg = Scene.v().getCallGraph();

		return cg;
	}

	public static CallGraph cgGen(String[] pkgList, String[][] clsList,
			String mainClassName) {
		Options.v().set_whole_program(true);
		Options.v().set_keep_line_number(true);
		// Options.v().setPhaseOption("cg", "verbose:true");
		Options.v().setPhaseOption("cg", "safe-forname:true");
		Options.v().setPhaseOption("cg", "safe-newinstance:true");

		ClassLoader.loadClass(pkgList, clsList, mainClassName);

		CHATransformer.v().transform();

		CallGraph cg = Scene.v().getCallGraph();

		return cg;
	}

}
